from ctaf_core.ctaf_objects.base_data_objects import BaseEventData, reconstruct_event_data_from_dict
from ctaf_core.log_trace_bundle.logging import LoggerFactory
from ctaf_facade.enumerations.event_type_enum import EventTypeEnum
from ctaf_facade.enumerations.msg_topic_enum import MsgTopicEnum
from typing import Any, Dict


#所有事件的基类
class BaseEvent:

    def __init__(self, event_type: EventTypeEnum, event_data: BaseEventData = None):
        self.event_type = event_type
        self.event_data = event_data

    def get_event_data(self):
        return self.event_data

    def get_event_type(self):
        return self.event_type

    def get_event_type_str(self):
        return self.event_type.value

    def get_event_in_str(self)->str:
        event_data_str = self.event_data.get_event_data_in_str() if self.event_data else "None"
        return f"event type is: {self.event_type}, event data is: {event_data_str}"

    def to_dict(self) -> Dict[str, Any]:
        """Converts the BaseEvent object to a dictionary for Msgpack serialization."""
        return {
            "event_type": self.event_type.value,
            "event_data": self.event_data.to_dict() if self.event_data else None
        }

    @classmethod
    def from_dict(cls, data: Dict[str, Any]):
        """Reconstructs a BaseEvent object from a dictionary."""
        event_type = EventTypeEnum(data["event_type"])
        event_data = None
        if data.get("event_data") is not None:
            # 使用工厂函数根据 event_type 反序列化正确的 BaseEventData 子类
            event_data = reconstruct_event_data_from_dict(event_type, data["event_data"])
        return cls(event_type, event_data)

'''
所有通过分布式总线发布消费消息事件基类
msg_topic仅有用于bus client过滤消息，即bus client仅处理其topic列表里的消息事件
消息事件被bus client接收到本地之后，放入本地的事件驱动引擎，本地事件处理器可以不再关注msg_topic
'''
class MsgEvent(BaseEvent):
    def __init__(self, event_type: EventTypeEnum, event_data: BaseEventData = None, msg_topic: MsgTopicEnum = MsgTopicEnum.DEFAULT_TOPIC):
        super().__init__(event_type, event_data)
        self.msg_topic = msg_topic.value

    def get_msg_topic_as_str(self):
        return self.msg_topic

    def to_dict(self) -> Dict[str, Any]:
        """Converts the MsgEvent object to a dictionary for Msgpack serialization."""
        base_dict = super().to_dict()
        base_dict["msg_topic"] = self.msg_topic
        return base_dict

    @classmethod
    def from_dict(cls, data: Dict[str, Any]):
        """Reconstructs a MsgEvent object from a dictionary."""
        # 先通过父类的 from_dict 方法重建基础事件部分
        base_event = super().from_dict(data)
        # 然后使用 msg_topic 来构建 MsgEvent
        msg_topic = MsgTopicEnum(data["msg_topic"])
        return cls(base_event.event_type, base_event.event_data, msg_topic)


'''
定义一个系统终止事件
'''
class SysTerminateEvent(BaseEvent):
    def __init__(self):
        # 系统终止事件通常没有 event_data
        super().__init__(EventTypeEnum.EVENT_SYS_TERMINATE, event_data=None)

    def to_dict(self) -> Dict[str, Any]:
        """Converts the SysTerminateEvent object to a dictionary for Msgpack serialization."""
        # 只需要事件类型
        return {"event_type": self.event_type.value}

    @classmethod
    def from_dict(cls, data: Dict[str, Any]):
        """Reconstructs a SysTerminateEvent object from a dictionary."""
        # 对于系统终止事件，直接实例化即可
        return cls()


def msgpack_event_default(obj):
    """
    Default encoder for msgpack. Handles custom objects like BaseEvent and its subclasses
    by converting them to a dictionary representation.
    """
    if isinstance(obj, BaseEvent):
        d = obj.to_dict()
        d["__event_class__"] = obj.__class__.__name__
        return d
    raise TypeError(f"Object of type {obj.__class__.__name__} is not Msgpack serializable")


def reconstruct_event_object_hook(dct):
    """
    Msgpack object hook for decoding custom event objects.
    This function reconstructs the correct Event object based on the '__event_class__' field.
    """
    if "__event_class__" in dct:
        class_name = dct["__event_class__"]
        if class_name == "SysTerminateEvent":
            return SysTerminateEvent.from_dict(dct)
        elif class_name == "MsgEvent":
            return MsgEvent.from_dict(dct)
        try:
            return BaseEvent.from_dict(dct)
        except Exception as e:
            LoggerFactory.get_logger().write_error_log(
                f"Failed to reconstruct event of type {class_name}: {e}. Returning raw dict.")
            return dct
    return dct